package io.gitee.terralian.code.generator.conf;

import java.io.File;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 在测试环境
 */
@Slf4j
@Configuration
public class DataSourceConf {

    private static final String SQLITE_URL_TEMPLATE = "jdbc:sqlite:{}";
    private static final String SQLITE_FILE = "/cache/msc.sqlite";
    private static final String SQLITE_INIT_SCRIPT = "sql/sqlite.sql";

    @Bean
    @Conditional(SqliteCondition.class)
    public HikariDataSource dataSource() {
        String webRoot = FileUtil.getWebRoot().getAbsolutePath();
        String sqliteFile = webRoot + SQLITE_FILE;
        String sqliteUrl = StrUtil.format(SQLITE_URL_TEMPLATE, sqliteFile);

        log.info("当前生成器数据源使用sqlite：" + sqliteFile);

        boolean isInit = initSqliteFile(sqliteFile);

        HikariConfig config = new HikariConfig();
        config.setDriverClassName("org.sqlite.JDBC");
        config.setJdbcUrl(sqliteUrl);
        config.setMinimumIdle(5);
        config.setMaximumPoolSize(15);
        config.setConnectionTestQuery("SELECT 1");
        config.setMaxLifetime(1800000);
        config.setConnectionTimeout(30000);
        config.setPoolName("HikariCP");

        HikariDataSource dataSource = new HikariDataSource(config);
        if (isInit) {
            initSqliteTable(dataSource);
        }
        return dataSource;
    }

    @SuppressWarnings("ResultOfMethodCallIgnored")
    private boolean initSqliteFile(String sqliteUrl) {
        File file = new File(sqliteUrl);
        if (file.exists()) {
            return false;
        }
        try {
            file.getParentFile().mkdirs();
            file.createNewFile();
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private void initSqliteTable(HikariDataSource dataSource) {
        String sql = ResourceUtil.readUtf8Str(SQLITE_INIT_SCRIPT);
        String[] sqlList = sql.split(";");
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        for (String sqlScript : sqlList) {
            if (sqlScript.contains("CREATE")) {
                jdbcTemplate.execute(sqlScript);
            }
        }
    }
}
